/***********************************************************************************************************
* TNA - The Network Auditor
* Copyright © 2012  Jeff Scaparra -- SPAWAR Systems Center LANT
*
* This file is a part of TNA.
*
*  Description:
*
*  This file defines the tcpserviceportdiscoverer module. This module is will listen to TCP network
*  connections and indentify services that are running on netblocks that the user specifies. By using a
*  wildcard netblock i.e. anything 0.0.0.0/0 this will identify all TCP services. No protocol detection is
*  built in and services are assumed to be running on the correct ports. In the event that a ssh server is
*  running on port 80 or something else weird it will be recorded at a TCP service on port 80 and the user
*  or another module would need to verify that the service was http or in this example find that it really was
*  ssh.
*
*
**************************************************************************************************************/

#ifndef TCPSERVICEPORTDISCOVERER_H
#define TCPSERVICEPORTDISCOVERER_H

#include <QMap>
#include <QPair>
#include <QVector>

#include <Packet/packet.h>
#include <string>
#include <iostream>
#include <fstream>
#include <QDateTime>

/*
  Database Storage:

  IP (v4 or v6)
  Service Port( )
  Service Names( ) (Should be already in the database or reloaded/updated based on user command)
  First Seen
  Last Seen
  Number of Clients
  Top 10 Clients
  Last 10 Clients
*/

/*
  ToDo:
  Filtering for netblocks, so that we only find servers in that netblock
*/


/* Needs to track
initial seq num
initital source ip
initial destination ip
initial dport
initial sport

Close ports send rst ack
*/

typedef struct ServiceQueueData
{
  uint16_t sequenceNum;
  QDateTime timestamp;
}ServiceQueueData;

//discovers services that have been connected to with a syn followed by a syn ack...

class TCPServicePortDiscoverer
{
public:
    TCPServicePortDiscoverer();
    ~TCPServicePortDiscoverer();
    void processPacket( const Packet &p );
    void setLogToFile( const bool &enable );
    void setLogToStdOut( const bool &enable );
    void setLogFile( const std::string &filename );
    void setUTC( const bool &enable );
    void setTimestampString( const std::string &format );
    void clearV4Netblocks();
    void addV4Netblock( const IPv4Address &network, const IPv4Address &netmask );
    QVector< QPair< IPv4Address, IPv4Address > > v4Netblocks() const;
    void clearV6Netblocks();
    void addV6Netblock( const IPv6Address &network, const IPv6Address &netmask );
    QVector< QPair< IPv6Address, IPv6Address > > v6Netblocks() const;
    std::string timestampFormat() const;
    bool utc() const;
    bool logToFile() const;
    bool logToStdOut() const;
    std::string logFile() const;


private:
   void removeConnection( const std::string &sourceString, const std::string &destinationString );
   bool isInV4Netblocks( const IPv4Address &address ) const;
   bool isInV6Netblocks( const IPv6Address &address ) const;
   void log( const std::string &message ); //outputs to user specified channels

  //format "<destination ip>:<destination port> -> <source ip>:<port num> ->  data;
  QMap< std::string, QMap< std::string, ServiceQueueData > > synQueue_;
  bool logToFile_;
  bool logToStdOut_;
  bool logToDB_;
  bool useUTC_;
  std::string filename_;
  std::ofstream *file_;
  std::string timestampFormat_;

  //QPairs are network, netmask
  QVector< QPair< IPv4Address, IPv4Address > > v4Netblocks_; //netblocks to look for services
  QVector< QPair< IPv6Address, IPv6Address > > v6Netblocks_; //netblocks to look for services



};

#endif // SERVICEPORTDISCOVERER_H
